Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit e0176545c403d39c353f9a7e43e2a31fae55ebc8


Parents : 6a75e67
Author : Ivan <ivan@quad4.io>
Signature : Invalid signer <e46112d44649266d71fe2193e00a4710>, author is <ivan@quad4.io>
Date : 2026-07-15T13:34:18-05:00

test: update notification tests by refactoring HTTP request handling and mocking asyncio.to_thread

Changes

3 files changed, 27 insertions(+), 26 deletions(-)


Diff

diff --git a/meshchatx.rsm b/meshchatx.rsm
index c51f9acb..0f25bfc8 100644
Binary files a/meshchatx.rsm and b/meshchatx.rsm differ

diff --git a/tests/backend/conftest.py b/tests/backend/conftest.py
index 92f046cb..ccab30bb 100644
--- a/tests/backend/conftest.py
+++ b/tests/backend/conftest.py
@@ -202,6 +202,16 @@ def mock_app(db, tmp_path, temp_db):
patch("meshchatx.src.backend.identity_context.AnnounceManager"),
)
stack.enter_context(patch("threading.Thread"))
+ # threading.Thread is mocked to prevent background threads, but that also
+ # breaks asyncio.to_thread (used by the HTTP layer for DB queries). Run
+ # those calls synchronously so integration tests do not hang waiting for a
+ # MagicMock thread that never starts.
+ stack.enter_context(
+ patch(
+ "asyncio.to_thread",
+ side_effect=lambda fn, *args, **kwargs: fn(*args, **kwargs),
+ ),
+ )
mock_id = MockIdentityClass()
mock_id.get_private_key = MagicMock(return_value=b"test_private_key")

diff --git a/tests/backend/test_notification_user_facing_filter.py b/tests/backend/test_notification_user_facing_filter.py
index b15ed13e..168e464a 100644
--- a/tests/backend/test_notification_user_facing_filter.py
+++ b/tests/backend/test_notification_user_facing_filter.py
@@ -756,10 +756,10 @@ class TestNotificationsGetUserFacingFilter:
class TestNotificationsMarkReadSync:
"""Reading a conversation must clear the bell without opening the dropdown."""
- async def _get(self, app, **params):
+ async def _get(self, app, path="/api/v1/notifications", **params):
aio_app = _build_aio_app(app)
async with TestClient(TestServer(aio_app)) as client:
- resp = await client.get("/api/v1/notifications", params=params)
+ resp = await client.get(path, params=params)
assert resp.status == 200
return await resp.json()
@@ -831,32 +831,23 @@ class TestNotificationsMarkReadSync:
timestamp=1_700_000_000,
),
)
- aio_app = _build_aio_app(bell_app)
- async with TestClient(TestServer(aio_app)) as client:
- conv_before = await client.get(
- "/api/v1/lxmf/conversations",
- params={"filter_unread": "true"},
- )
- assert conv_before.status == 200
- assert len((await conv_before.json())["conversations"]) == 1
- await client.post(f"/api/v1/lxmf/conversations/{PEER_HASH}/mark-as-read")
+ conv_before = await self._get(
+ bell_app, path="/api/v1/lxmf/conversations", filter_unread="true"
+ )
+ assert len(conv_before["conversations"]) == 1
- conv_after = await client.get(
- "/api/v1/lxmf/conversations",
- params={"filter_unread": "true"},
- )
- bell_after = await client.get(
- "/api/v1/notifications",
- params={"unread": "true", "limit": 10},
- )
- assert conv_after.status == 200
- assert bell_after.status == 200
- conv_body = await conv_after.json()
- bell_body = await bell_after.json()
- assert conv_body["conversations"] == []
- assert bell_body["unread_count"] == 0
- assert bell_body["notifications"] == []
+ await self._post(
+ bell_app, f"/api/v1/lxmf/conversations/{PEER_HASH}/mark-as-read"
+ )
+
+ conv_after = await self._get(
+ bell_app, path="/api/v1/lxmf/conversations", filter_unread="true"
+ )
+ bell_after = await self._get(bell_app, unread="true", limit=10)
+ assert conv_after["conversations"] == []
+ assert bell_after["unread_count"] == 0
+ assert bell_after["notifications"] == []
async def test_read_conversation_with_reaction_latest_stays_clear(self, bell_app):
bell_app.database.messages.upsert_lxmf_message(


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────